package fr.enseirb.collabs.rest;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;

import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;

import fr.enseirb.collabs.model.Skill;
import fr.enseirb.collabs.persistence.MemoryDataBundle;

@Path("/skills")
public class SkillsREST {

	private MemoryDataBundle model;
	private ObjectMapper mapper;

	public SkillsREST() {
		mapper = new ObjectMapper();
		model = MemoryDataBundle.getInstance();
	}

	// //////////////////////
	// GET METHODS : QUERY
	// //////////////////////

	@GET
	@Produces(MediaType.APPLICATION_JSON)
	public String getAllSkills() {
		try {
			return mapper.writeValueAsString(model.getSkills());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	@GET
	@Path("{id}")
	@Produces(MediaType.APPLICATION_JSON)
	public String getSkillById(@PathParam("id") int id) {
		try {
			return mapper.writeValueAsString(model.getSkillByID(id));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	@GET
	@Path("{id}/subs")
	@Produces(MediaType.APPLICATION_JSON)
	public String getSubSkill(@PathParam("id") int id) {
		try {
			Collection<Skill> subs = new ArrayList<Skill>();
			for (Skill s : model.getSkills()) {
				if (new Integer(id).equals(s.getParent_id())) {
					subs.add(s);
				}
			}
			return mapper.writeValueAsString(subs);
		} catch (JsonGenerationException e) {
			e.printStackTrace();
		} catch (JsonMappingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		return null;
	}

	// ////////////////////
	// POST METHODS : ADD
	// ////////////////////

	@POST
	@Produces(MediaType.APPLICATION_JSON)
	public String addSkill(String json) {

		try {
			Skill s = mapper.readValue(json, Skill.class);
			if (s == null) {
				return mapper.writeValueAsString(new Boolean(false));
			}
			model.addSkill(s);
			return mapper.writeValueAsString(new Boolean(true));
		} catch (JsonGenerationException e) {
			e.printStackTrace();
		} catch (JsonMappingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		return null;
	}

	@PUT
	@Path("{id}")
	@Produces(MediaType.APPLICATION_JSON)
	public String updateSkill(@PathParam("id") int id, String json) {

		try {
			Skill updated = mapper.readValue(json, Skill.class);
			Skill old = model.getSkillByID(id);

			old.setName(updated.getName());
			old.setDescription(updated.getDescription());
			old.setParent_id(updated.getParent_id());

			return mapper.writeValueAsString(new Boolean(true));
		} catch (JsonParseException e) {
			e.printStackTrace();
		} catch (JsonMappingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		return null;
	}

	// ////////////////////
	// DELETE METHODS : DELETE
	// ////////////////////

	@DELETE
	@Path("{id}")
	@Produces(MediaType.APPLICATION_JSON)
	public String deleteSkill(@PathParam("id") int id) {

		try {
			model.deleteSkill(id);
			return mapper.writeValueAsString(new Boolean(true));
		} catch (JsonParseException e) {
			e.printStackTrace();
		} catch (JsonMappingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		return null;
	}
}
